<template>
    <children v-if="list.length != 0" :list="list" :select="select" :collect="collect" />
</template>

<script setup lang="ts">
import {Api} from '@/api/type'
import {onMounted, ref} from 'vue'
import {useMessage} from 'naive-ui'
import Children from './children.vue'
import {BaseApi} from '@/api/base-api'
// ---------------------------------------
type R<T> = Api.Common.R<T>;
type Data = Api.System.Route;
type Option = Api.System.RouteOption;
// ---------------------------------------

const select = defineModel<Map<string, boolean>>('select', {
    required: true
})

const message = useMessage()
const baseApi = new BaseApi<Data>('route')

const list = ref<Array<Option>>([])
const collect = ref<Map<string, Option[]>>(new Map<string, Option[]>)

async function getRouteList(): Promise<Array<Data>> {
    let result: R<Array<Data>> = await baseApi.getDataList()
    if (result.code == 0) {
        return result.data || []
    } else {
        console.error(result.message)
        message.error(result.message)
        return []
    }
}

/**
 * 组装用户路由树
 */
const generateTree = (list: Array<Data>): Array<Option> => {
    let _list: Array<Option> = list.map((item: Data): Option => {
        if (!select.value.get(item.identity)) {
            select.value.set(item.identity, false)
        }
        return {
            identity: item.identity,
            parent: item.parent,
            type: item.type,
            name: item.name,
            select: select.value.get(item.identity),
            children: [],
            permission: []
        } as Option
    })

    let _map: Map<string, Option> = _list.reduce((map: Map<string, Option>, item: Option) => {
        map.set(item.identity, item)
        return map
    }, new Map<string, Option>())

    _list.forEach((item: Option) => {
        let parent: Option | undefined = _map.get(item.parent)
        let current: Option | undefined = _map.get(item.identity)
        if (parent) {
            if (current && [1, 2].includes(current.type as number)) {
                parent.children?.push(current)
            }
            if (current && current.type == 3) {
                parent.permission?.push(current)
            }
            _map.set(item.parent, parent)
        }

        //
        let _collect = collect.value.get(item.parent) || []
        _collect.push(item)
        collect.value.set(item.parent, _collect)

    })
    return _list.filter((item: Option): boolean => item.parent == '0')
}

async function initialize() {
    let routeList = await getRouteList()
    list.value = generateTree(routeList)
}

onMounted(() => {
    initialize()
})
</script>
